// Copyright 2022 PingCAP, Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <Common/FileChecker.h>
#include <Common/escapeForFileName.h>
#include <Core/Defines.h>
#include <Poco/File.h>
#include <Storages/IStorage.h>

#include <ext/shared_ptr_helper.h>
#include <map>
#include <shared_mutex>


namespace DB
{
/** Implements a table engine that is suitable for small chunks of the log.
  * In doing so, stores all the columns in a single Native file, with a nearby index.
  */
class StorageStripeLog : public ext::SharedPtrHelper<StorageStripeLog>
    , public IStorage
{
    friend class StripeLogBlockInputStream;
    friend class StripeLogBlockOutputStream;

public:
    std::string getName() const override { return "StripeLog"; }
    std::string getTableName() const override { return name; }

    BlockInputStreams read(
        const Names & column_names,
        const SelectQueryInfo & query_info,
        const Context & context,
        QueryProcessingStage::Enum & processed_stage,
        size_t max_block_size,
        unsigned num_streams) override;

    BlockOutputStreamPtr write(const ASTPtr & query, const Settings & settings) override;

    void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override;

    bool checkData() const override;

    /// Data of the file.
    struct ColumnData
    {
        Poco::File data_file;
    };
    using Files_t = std::map<String, ColumnData>;

    std::string full_path() const { return path + escapeForFileName(name) + '/'; }

    String getDataPath() const override { return full_path(); }

private:
    String path;
    String name;

    size_t max_compress_block_size;

    FileChecker file_checker;
    mutable std::shared_mutex rwlock;

    Poco::Logger * log;

protected:
    StorageStripeLog(
        const std::string & path_,
        const std::string & name_,
        const ColumnsDescription & columns_,
        bool attach,
        size_t max_compress_block_size_);
};

} // namespace DB
